const qiniu = require('qiniu')
const axios = require('axios')
const fs = require('fs')
const { resolve } = require('path')
class QiniuManager {
    constructor (accessKey, secretKey, bucket) {
        this.mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
        this.bucket = bucket
        this.config = new qiniu.conf.Config()
        this.config.zone = qiniu.zone.Zone_z0
        this.bucketManager = new qiniu.rs.BucketManager(this.mac, this.config);
    }
    uploadFile(key, localFilePath) {
        var options = {
            scope: this.bucket + ":" + key,
        }
        var putPolicy = new qiniu.rs.PutPolicy(options);
        var uploadToken=putPolicy.uploadToken(this.mac);
        var formUploader = new qiniu.form_up.FormUploader(this.config);
        var putExtra = new qiniu.form_up.PutExtra();
        return new Promise((resolve, reject) => {
            formUploader.putFile(uploadToken, key, localFilePath, putExtra, this._handleCallback(resolve, reject))
        })
  
    }
    deleteFile(key) {
        return new Promise((resolve, reject) => {
            bucketManager.delete(this.bucket, key, this._handleCallback(resolve, reject));
        })
    }
    _handleCallback(resolve, reject) {
        return (respErr, respBody, respInfo) => {
            if (respErr) {
                throw respErr;
            }
            if (respInfo.statusCode == 200) {
                resolve(respBody);
            } else {
                reject({statusCode: respInfo.statusCode, body: respBody})
            }
        }
    }
    downLoadFile (key, downLoadPath) {
        this.generateDownloadLink(key).then(link => {
            const timeStamp = new Date().getTime()
            const url = `${link}?timestamp=${timeStamp}`
            axios({
                method: 'GET',
                url,
                responseType: 'stream',
                headers: {'Cache-Control': 'no-cache'}
            }).then(response => {
                const writer = fs.createWriteStream(downLoadPath)
                response.data.pipe(writer)
                return new Promise((resolve, reject) => {
                    writer.on('finish', resolve)
                    writer.on('error', reject)
                })
            }).catch(err => {
                return Promise.resolve({ err: err.response })
            }) 

        })
    }
    getBucketDomain () {
        const reqURL = `http://api.qiniu.com/v6/domain/list?tbl=${this.bucket}`
        const digest = qiniu.util.generateAccessToken(this.mac, reqURL)
        return new Promise((resolve, reject) => {
            qiniu.rpc.postWithoutForm(reqURL, digest, this._handleCallback(resolve, reject))
        })
    }
    generateDownloadLink(key) {
        const domainPromise = this.publicBucketDomain ? Promise.resolve([this.getBucketDomain]) : this.getBucketDomain()
        return domainPromise.then(data => {
            if(Array.isArray(data) && data.length > 0) {
                const pattern = /^https?/
                this.publicBucketDomain = pattern.test(data[0]) ? data[0] : `http://${data[0]}`
                return this.bucketManager.publicDownloadUrl(this.publicBucketDomain, key)
            } else {
                throw Error('域名未找到')
            }
        })
    }
    getStat (key) {
        return new Promise((resolve, reject) => {
            this.bucketManager.stat(this.bucket, key, this._handleCallback(resolve, reject))
        })
    }
}

module.exports = QiniuManager 